package com.reactim.user.service.impl;

import com.reactim.user.entity.FriendRequest;
import com.reactim.user.entity.UserFriend;
import com.reactim.user.entity.UserPrivacySetting;
import com.reactim.user.repository.FriendRequestRepository;
import com.reactim.user.repository.UserFriendRepository;
import com.reactim.user.repository.UserPrivacySettingRepository;
import com.reactim.user.service.FriendRequestService;
import com.reactim.user.service.FriendNotificationService;
import com.reactim.user.service.UserService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDateTime;
import java.util.Arrays;
import java.util.Optional;

/**
 * 好友请求服务实现
 */
@Slf4j
@Service
@RequiredArgsConstructor
public class FriendRequestServiceImpl implements FriendRequestService {
    
    private final FriendRequestRepository friendRequestRepository;
    private final UserFriendRepository userFriendRepository;
    private final UserPrivacySettingRepository privacySettingRepository;
    private final UserService userService;
    private final FriendNotificationService friendNotificationService;
    
    // 好友请求过期时间（30天）
    private static final int REQUEST_EXPIRE_DAYS = 30;
    
    @Override
    @Transactional
    public FriendRequest sendFriendRequest(Long fromUserId, Long toUserId, String message) {
        // 验证用户
        if (fromUserId.equals(toUserId)) {
            throw new IllegalArgumentException("不能向自己发送好友请求");
        }
        
        // 检查目标用户是否存在
        if (!userService.existsById(toUserId)) {
            throw new IllegalArgumentException("目标用户不存在");
        }
        
        // 检查是否已经是好友
        if (userFriendRepository.existsByUserIdAndFriendId(fromUserId, toUserId)) {
            throw new IllegalArgumentException("已经是好友关系");
        }
        
        // 检查是否可以发送请求
        if (!canSendFriendRequest(fromUserId, toUserId)) {
            throw new IllegalArgumentException("无法向该用户发送好友请求");
        }
        
        // 检查是否已有待处理的请求
        Optional<FriendRequest> existingRequest = friendRequestRepository
                .findByFromUserIdAndToUserIdAndStatus(fromUserId, toUserId, FriendRequest.RequestStatus.PENDING);
        
        if (existingRequest.isPresent()) {
            throw new IllegalArgumentException("已有待处理的好友请求");
        }
        
        // 创建好友请求
        FriendRequest request = new FriendRequest();
        request.setFromUserId(fromUserId);
        request.setToUserId(toUserId);
        request.setMessage(message);
        request.setStatus(FriendRequest.RequestStatus.PENDING);
        request.setExpiredAt(LocalDateTime.now().plusDays(REQUEST_EXPIRE_DAYS));
        
        FriendRequest savedRequest = friendRequestRepository.save(request);
        
        // 发送通知
        friendNotificationService.sendFriendRequestNotification(savedRequest);
        
        log.info("好友请求已发送: fromUserId={}, toUserId={}, requestId={}", 
                fromUserId, toUserId, savedRequest.getId());
        
        return savedRequest;
    }
    
    @Override
    @Transactional
    public void acceptFriendRequest(Long requestId, Long userId) {
        FriendRequest request = friendRequestRepository.findById(requestId)
                .orElseThrow(() -> new IllegalArgumentException("好友请求不存在"));
        
        // 验证权限
        if (!request.getToUserId().equals(userId)) {
            throw new IllegalArgumentException("无权处理此好友请求");
        }
        
        // 验证状态
        if (request.getStatus() != FriendRequest.RequestStatus.PENDING) {
            throw new IllegalArgumentException("请求状态无效");
        }
        
        // 检查是否过期
        if (request.getExpiredAt() != null && request.getExpiredAt().isBefore(LocalDateTime.now())) {
            request.setStatus(FriendRequest.RequestStatus.EXPIRED);
            friendRequestRepository.save(request);
            throw new IllegalArgumentException("好友请求已过期");
        }
        
        // 更新请求状态
        request.setStatus(FriendRequest.RequestStatus.ACCEPTED);
        request.setProcessedAt(LocalDateTime.now());
        friendRequestRepository.save(request);
        
        // 创建双向好友关系
        createFriendRelation(request.getFromUserId(), request.getToUserId());
        createFriendRelation(request.getToUserId(), request.getFromUserId());
        
        // 发送通知
        friendNotificationService.sendFriendRequestAcceptedNotification(request);
        friendNotificationService.sendNewFriendAddedNotification(request.getFromUserId(), request.getToUserId());
        friendNotificationService.sendNewFriendAddedNotification(request.getToUserId(), request.getFromUserId());
        
        log.info("好友请求已接受: requestId={}, fromUserId={}, toUserId={}", 
                requestId, request.getFromUserId(), request.getToUserId());
    }
    
    @Override
    @Transactional
    public void rejectFriendRequest(Long requestId, Long userId, String reason) {
        FriendRequest request = friendRequestRepository.findById(requestId)
                .orElseThrow(() -> new IllegalArgumentException("好友请求不存在"));
        
        // 验证权限
        if (!request.getToUserId().equals(userId)) {
            throw new IllegalArgumentException("无权处理此好友请求");
        }
        
        // 验证状态
        if (request.getStatus() != FriendRequest.RequestStatus.PENDING) {
            throw new IllegalArgumentException("请求状态无效");
        }
        
        // 更新请求状态
        request.setStatus(FriendRequest.RequestStatus.REJECTED);
        request.setRejectReason(reason);
        request.setProcessedAt(LocalDateTime.now());
        friendRequestRepository.save(request);
        
        // 发送通知
        friendNotificationService.sendFriendRequestRejectedNotification(request);
        
        log.info("好友请求已拒绝: requestId={}, reason={}", requestId, reason);
    }
    
    @Override
    @Transactional
    public void cancelFriendRequest(Long requestId, Long userId) {
        FriendRequest request = friendRequestRepository.findById(requestId)
                .orElseThrow(() -> new IllegalArgumentException("好友请求不存在"));
        
        // 验证权限
        if (!request.getFromUserId().equals(userId)) {
            throw new IllegalArgumentException("无权取消此好友请求");
        }
        
        // 验证状态
        if (request.getStatus() != FriendRequest.RequestStatus.PENDING) {
            throw new IllegalArgumentException("请求状态无效");
        }
        
        // 更新请求状态
        request.setStatus(FriendRequest.RequestStatus.CANCELLED);
        request.setProcessedAt(LocalDateTime.now());
        friendRequestRepository.save(request);
        
        // 发送通知
        friendNotificationService.sendFriendRequestCancelledNotification(request);
        
        log.info("好友请求已取消: requestId={}", requestId);
    }
    
    @Override
    public Page<FriendRequest> getReceivedRequests(Long userId, Pageable pageable) {
        return friendRequestRepository.findByToUserIdAndStatusOrderByCreatedAtDesc(
                userId, FriendRequest.RequestStatus.PENDING, pageable);
    }
    
    @Override
    public Page<FriendRequest> getSentRequests(Long userId, Pageable pageable) {
        return friendRequestRepository.findByFromUserIdAndStatusOrderByCreatedAtDesc(
                userId, FriendRequest.RequestStatus.PENDING, pageable);
    }
    
    @Override
    public long getPendingRequestCount(Long userId) {
        return friendRequestRepository.countByToUserIdAndStatus(
                userId, FriendRequest.RequestStatus.PENDING);
    }
    
    @Override
    public boolean canSendFriendRequest(Long fromUserId, Long toUserId) {
        // 获取目标用户的隐私设置
        Optional<UserPrivacySetting> privacyOpt = privacySettingRepository.findByUserId(toUserId);
        
        if (privacyOpt.isEmpty()) {
            return true; // 没有设置隐私，默认允许
        }
        
        UserPrivacySetting privacy = privacyOpt.get();
        
        switch (privacy.getFriendRequestPermission()) {
            case NOBODY:
                return false;
            case CONTACTS_ONLY:
                // TODO: 实现联系人检查逻辑
                return false;
            case FRIENDS_OF_FRIENDS:
                // TODO: 实现朋友的朋友检查逻辑
                return checkFriendsOfFriends(fromUserId, toUserId);
            case EVERYONE:
            default:
                return true;
        }
    }
    
    @Override
    @Transactional
    public int cleanupExpiredRequests() {
        LocalDateTime now = LocalDateTime.now();
        int count = friendRequestRepository.updateExpiredRequests(
                FriendRequest.RequestStatus.PENDING,
                FriendRequest.RequestStatus.EXPIRED,
                now,
                now
        );
        
        log.info("清理过期好友请求: {} 条", count);
        return count;
    }
    
    /**
     * 创建好友关系
     */
    private void createFriendRelation(Long userId, Long friendId) {
        UserFriend userFriend = new UserFriend();
        userFriend.setUserId(userId);
        userFriend.setFriendId(friendId);
        userFriend.setStatus(UserFriend.FriendStatus.NORMAL);
        userFriendRepository.save(userFriend);
    }
    
    /**
     * 检查是否为朋友的朋友
     */
    private boolean checkFriendsOfFriends(Long fromUserId, Long toUserId) {
        // 获取fromUserId的所有好友
        // 检查这些好友中是否有人也是toUserId的好友
        // 简化实现，实际需要更复杂的查询
        return false;
    }
}